home *** CD-ROM | disk | FTP | other *** search
- /**
- ** author dan O'Donnell, James Painter
- ** purpose Reconstruct the image function from stochastic sample file
- **
- **/
-
- #include <stdio.h>
- #include <math.h>
- #include <assert.h>
- #include "Reconstruct.h"
- #include "wff.h"
-
- /*
- ** Test to see if two rectangles overlap. Return TRUE if the do, FALSE
- ** otherwise.
- */
- #define RectOverlap(Rect1,Rect2) \
- ( ! ( (Rect1)->xH < (Rect2)->xL || (Rect2)->xH < (Rect1)->xL || \
- (Rect1)->yH < (Rect2)->yL || (Rect2)->yH < (Rect1)->yL ))
-
-
- /*------------------------------------
- Check to see if the point X,Y is in
- the rectangle Rect.
- ------------------------------------*/
- #define PointInRectangle(Xs,Ys,Rect) \
- ( ((Xs) >= (Rect)->xL) && ((Xs) < (Rect)->xH) && \
- ((Ys) >= (Rect)->yL) && ((Ys) < (Rect)->yH) )
-
-
-
- /* Number of nodes/samples to allocate at a time */
- #define GLOB_SIZE 1024
-
-
-
- /*----------------------------------------
- Subdivision level
- --------------------------------------*/
- static
- int level;
-
- int AdaptiveSplits = FALSE;
- int Animating = FALSE;
-
- HierarchicalRegion Root;
- RectType RootBoundary;
-
- extern double atof();
- extern HierarchicalRegion *PropagateSample();
- extern FloatColor FilterFinalize();
- extern char *mallocNd();
-
- int window; /* TRUE if sinc function is windowed */
-
- static FILE *NumRaysImage = NULL;
- int Xsize = 128, Ysize = 128;
- int x_start=0, y_start=0, x_stop=127, y_stop=127;
- double PixelSizeX, PixelSizeY;
- double MaxInBandValue = 1.0; /* The maximum value expected in a color band */
-
- double FilterSupport = 3.0;
- static double Aspect = (6.0/5.3), FilterRadius = 1.25;
- double B = .3333333333, C = .33333333333; /* "Mitchell" cubic parameters */
- double CutOff = -1.0;
- FilterFunctionType FilterFunction = Gaussian;
-
- int BitsPerBand = 8; /* Output bits per band */
- long MaxOutBandValue = 255; /* The maximum value to output */
-
- FILE *image = NULL;
- char *filename;
-
- typedef struct {
- FloatColor clr;
- float weight;
- unsigned short samplesInPixel;
- } Pixel;
-
- Pixel **image_data;
-
- /* --------------------------------------------------------------------------
- Split a node boundary rectangle into the rectangle for the Left
- (if LeftOrRight == TRUE) or Right (if LeftOrRight == FALSE) subnode.
- ---------------------------------------------------------------------------*/
- SplitBoundary(LeftOrRight, splitDirection, splitValue,
- OldBoundary, NewBoundary)
- int LeftOrRight;
- double splitValue;
- RectType *OldBoundary, *NewBoundary;
- {
- double Xs, Ys;
-
- *NewBoundary = *OldBoundary;
- if ( splitDirection ) /* Odd levels split in X */
- { /* Split in X */
- Xs = splitValue;
- if (LeftOrRight) { /* Left Child */
- NewBoundary->xH = Xs;
- } else { /* Right child */
- NewBoundary->xL = Xs;
- }
- }
- else
- { /* Split in Y */
- Ys = splitValue;
- if (LeftOrRight) { /* Left Child */
- NewBoundary->yH = Ys;
- } else { /* Right Child */
- NewBoundary->yL = Ys;
- }
- }
- }
-
-
-
- /*-----------------------
- allocate a node
- ----------------------*/
-
- static
- HierarchicalRegion *
- CreateNode()
- {
- char *calloc();
- static HierarchicalRegion *FreeNodes;
- static nFreeNodes = 0;
-
-
- if (nFreeNodes <= 0) {
- FreeNodes = (HierarchicalRegion *)
- calloc( GLOB_SIZE, sizeof(HierarchicalRegion));
- if(FreeNodes == NULL)
- {
- fprintf(stderr,"Fatal error - Can't allocate nodes\n");
- abort();
- }
- nFreeNodes = GLOB_SIZE;
- }
- return &(FreeNodes[--nFreeNodes]);
- }
-
-
- static SampleData *SampleFreeList = NULL;
-
- FreeSample( Sample )
- SampleData *Sample;
- {
- /* Link the sample onto the free list */
- *( (SampleData **) Sample) = SampleFreeList;
- SampleFreeList = Sample;
- }
-
- SampleData *CreateSample()
- {
- char *calloc();
- static SampleData *FreeSamples, *Sample;
- static int nFreeSamples = 0;
-
- /* Get one off the free list if possible */
- if (SampleFreeList != NULL) {
- Sample = SampleFreeList;
- SampleFreeList = *( (SampleData **) SampleFreeList );
- bzero ( Sample, sizeof(SampleData) );
- return Sample;
- }
-
- if (nFreeSamples <= 0) {
- FreeSamples = (SampleData *) calloc( GLOB_SIZE, sizeof(SampleData));
- if(FreeSamples == NULL)
- {
- fprintf(stderr,"Fatal error - Can't allocate sample data\n");
- abort();
- }
- nFreeSamples = GLOB_SIZE;
- }
- return & (FreeSamples[--nFreeSamples]);
- }
-
- /* Split a node into two subnodes */
- SplitNode(Node)
- HierarchicalRegion *Node;
- {
- Node->Left = CreateNode();
- Node->Right = CreateNode();
- }
-
-
- /*-----------------------------
- propagate the current node's
- sample to one of the subnodes
- return the EMPTY SUBNODE
- ---------------------------*/
- HierarchicalRegion *PropagateSample(Node, Boundary, NewSample)
- HierarchicalRegion *Node;
- RectType *Boundary;
- SampleData *NewSample;
- {
- RectType LeftBoundary;
- double dx, dy;
-
- if (AdaptiveSplits) {
-
- /** Choose a split direction which separates the new sample
- ** from the old and maintains an aspect ratio as close to square
- ** as possible for the new sub cells.
- */
- double xsplit, ysplit, x1, x2, y1, y2, xratio, xratio2, yratio, yratio2;
- double width, height;
-
-
- /* Split at the mid point between samples */
- xsplit = 0.5*(Node->Sample->Xs + NewSample->Xs);
- ysplit = 0.5*(Node->Sample->Ys + NewSample->Ys);
-
- /* These are the side lengths of the sub cells */
- x1 = xsplit - Boundary->xL;
- x2 = Boundary->xH - xsplit;
- y1 = ysplit - Boundary->yL;
- y2 = Boundary->yH - ysplit;
-
- /* These are the side lengths of the whole cell */
- width = (Boundary->xH - Boundary->xL);
- height = (Boundary->yH - Boundary->yL);
-
- /* These are the aspect ratios if we split in x */
- if (x1 > height)
- xratio = (height < 1.0E-20) ? 1.0E20 : x1 / height;
- else
- xratio = (x1 < 1.0E-20) ? 1.0E20 : height / x1;
- if (x2 > height)
- xratio2 = (height < 1.0E-20) ? 1.0E20 : x2 / height;
- else
- xratio2 = (x2 < 1.0E-20) ? 1.0E20 : height / x2;
-
-
- /* Use the worst of the two for comparison */
- if (xratio2 > xratio) xratio = xratio2;
-
- /* These are the aspect ratios if we split in y */
- if (y1 > width)
- yratio = (width < 1.0E-20) ? 1.0E20 : y1 / width;
- else
- yratio = (y1 < 1.0E-20) ? 1.0E20 : width / y1;
- if (y2 > width)
- yratio2 = (width < 1.0E-20) ? 1.0E20 : y2 / width;
- else
- yratio2 = (y2 < 1.0E-20) ? 1.0E20 : width / y2;
-
-
- /* Use the worst of the two for comparison */
- if (yratio2 > yratio) yratio = yratio2;
-
- if (xratio < yratio) { /* X split is better */
- Node->splitDirection = 1; /* Split in X */
- Node->splitValue = 0.5*(Node->Sample->Xs + NewSample->Xs);
- } else {
- Node->splitDirection = 0; /* Split in Y */
- Node->splitValue = 0.5*(Node->Sample->Ys + NewSample->Ys);
- }
- } else {
- Node->splitDirection = (level & 1); /* Odd levels split in X */
- if (Node->splitDirection)
- Node->splitValue = 0.5*(Boundary->xL + Boundary->xH);
- else
- Node->splitValue = 0.5*(Boundary->yL + Boundary->yH);
- }
-
- SplitBoundary( TRUE, Node->splitDirection, Node->splitValue,
- Boundary, &LeftBoundary );
-
- if( (Node->Sample->Xs >= LeftBoundary.xL) &&
- (Node->Sample->Xs < LeftBoundary.xH) &&
- (Node->Sample->Ys >= LeftBoundary.yL) &&
- (Node->Sample->Ys < LeftBoundary.yH) )
- {
- Node->Left->Sample = Node->Sample;
- return Node->Right;
- }
- else
- {
- Node->Right->Sample = Node->Sample;
- return Node->Left;
- }
- }
-
-
- SampleData *ReadSample(file)
- FILE *file;
- {
- SampleData *Sample = CreateSample();
- long sibling; /* Index of sibling node */
-
- #ifdef BINARY
- {
- long array[7], *p = array;
- if (fread( array, sizeof(long), 7, file ) != 7) return 0;
- sibling = *((long *) p++);
- Sample->Xs = *((float *)p++);
- Sample->Ys = *((float *)p++);
- Sample->Ave.r = *((float *)p++);
- Sample->Ave.g = *((float *)p++);
- Sample->Ave.b = *((float *)p++);
- Sample->Ave.a = *((float *)p);
- }
- #else
- if (fscanf( file, "%d %f %f %f %f %f %f",
- &sibling, &Sample->Xs, &Sample->Ys,
- &Sample->Ave.r, &Sample->Ave.g, &Sample->Ave.b, &Sample->Ave.a )
-
- != 7) return 0;
- #endif
- return Sample;
- }
-
-
-
-
- /*---------------------------------
- Insert the new node in the tree.
- ----------------------------------*/
- InsertNode(NewSample, Root, RootBoundary, InterestingBoundary)
- SampleData *NewSample;
- HierarchicalRegion *Root;
- RectType *RootBoundary, *InterestingBoundary;
- {
- HierarchicalRegion *Node = Root, *EmptyNode;
- RectType Boundarys[2], *Boundary, *NewBoundary;
- int old, new;
-
-
- Boundarys[0] = *RootBoundary;
- old = 0; new = 1;
- Boundary = Boundarys+0;
- NewBoundary = Boundarys+1;
-
- /* Search down to the leaf level for the cell this sample belongs in */
- level = 0;
- while (!IsLeaf(Node))
- {
- if (!RectOverlap( InterestingBoundary, Boundary )) {
- /* Not in an interesting part of the image, ignore it */
- FreeSample( NewSample );
- return;
- }
- SplitBoundary( TRUE, Node->splitDirection, Node->splitValue,
- Boundary, NewBoundary );
- if (PointInRectangle( NewSample->Xs, NewSample->Ys, NewBoundary )) {
- Node = Node->Left;
- } else {
- SplitBoundary( FALSE, Node->splitDirection, Node->splitValue,
- Boundary, NewBoundary );
- Node = Node->Right;
- }
- old = (old +1) %2;
- new = (new +1) %2;
- Boundary = Boundarys+old;
- NewBoundary = Boundarys+new;
- level++;
- }
-
- /* Split the Node */
- SplitNode( Node );
-
- /* Fill in the two new cells */
- EmptyNode = PropagateSample(Node, Boundary, NewSample);
- EmptyNode->Sample = NewSample;
-
- if (Animating)
- AnimateShadeCell( Boundary, NewSample );
- }
-
-
- /*-----------------------
- Read the samples
- ----------------------*/
- ReadSampleFile( samplefile, InterestingBoundary )
- FILE *samplefile;
- RectType *InterestingBoundary; /* Region of interest */
- {
- /* read the boundary Rectangle */
- #ifdef BINARY
- {
- float array[4], *p=array;
- fread( array, sizeof(float), 4, samplefile );
- RootBoundary.xL = *p++;
- RootBoundary.yL = *p++;
- RootBoundary.xH = *p++;
- RootBoundary.yH = *p;
- }
- #else
- fscanf( samplefile, "%f %f %f %f",
- &RootBoundary.xL, &RootBoundary.yL,
- &RootBoundary.xH, &RootBoundary.yH );
- #endif
-
- Root.Left = Root.Right = (HierarchicalRegion *) NULL;
-
- /* Read the Root Node */
- Root.Sample = ReadSample( samplefile );
-
- while (!feof(samplefile)) {
- SampleData *Sample;
-
- if (Animating)
- AnimateCheckInput();
-
- /* Read the next node */
- Sample = ReadSample( samplefile );
- if (Sample == NULL)
- break;
-
- /* Insert this node in the tree */
- InsertNode( Sample, &Root, &RootBoundary, InterestingBoundary );
- }
- }
-
-
-
-
- /*
- ** Traverse the sample tree and add the contribution from each sample
- ** into all affected pixels.
- */
- static
- Filter( Root, RootBoundary )
- HierarchicalRegion *Root;
- RectType RootBoundary;
- {
- register HierarchicalRegion *Node;
- RectType LeftBoundary, RightBoundary, Boundary, Overlap;
- int Left, Right;
- float Xs, Ys;
-
- /* This stack is used to avoid the expense of recursion */
- HierarchicalRegion *NodeStack[MAX_DEPTH];
- RectType BoundaryStack[MAX_DEPTH];
- int levelStack[MAX_DEPTH];
- int nStack;
- int r, c, rmn, rmx, cmn, cmx;
- REAL x, y, yL, yH, xL, xH, Weight;
- Pixel *pixel;
- FloatColor *clr;
- extern double Gauss(), WindowedSincFunction(), CdfLookup();
-
- switch (FilterFunction) {
- case Gaussian:
- SetFilterSupport( FilterSupport );
- BuildCdf( Gauss );
- break;
- case Sinc:
- FilterSupport = FilterRadius;
- SetFilterSupport( FilterSupport );
- window = 0;
- BuildCdf( WindowedSincFunction );
- break;
- case WindowedSinc:
- FilterSupport = FilterRadius;
- SetFilterSupport( FilterSupport );
- window = 1;
- BuildCdf( WindowedSincFunction );
- break;
- case Cubic:
- FilterSupport = 2.0;
- CubicFilterSetup( B, C );
- break;
- default:
- fprintf( stderr, "Filter type: %d not available\n", FilterFunction );
- exit(1);
- }
-
- /* Start with the root node on the stack */
- nStack = 0;
- NodeStack[nStack] = Root;
- BoundaryStack[nStack] = RootBoundary;
- levelStack[nStack++] = 0;
-
- while (nStack > 0) {
-
- /* Get the next node to process from the stack */
- Node = NodeStack[--nStack];
- Boundary = BoundaryStack[nStack];
- level = levelStack[nStack];
-
- /* Follow the tree down a leaf, pushing the side branches.
- */
- while (! IsLeaf(Node)) {
-
- SplitBoundary( TRUE, Node->splitDirection, Node->splitValue,
- &Boundary, &LeftBoundary );
- if (Node->Left) {
- NodeStack[nStack] = Node->Left;
- BoundaryStack[nStack] = LeftBoundary;
- levelStack[nStack++] = level+1;
- }
- SplitBoundary( FALSE, Node->splitDirection, Node->splitValue,
- &Boundary, &RightBoundary );
- if (Node->Right) {
- if (nStack >= MAX_DEPTH) {
- fprintf( stderr, "Filter stack overflow!\n" );
- abort();
- }
- NodeStack[nStack] = Node->Right;
- BoundaryStack[nStack] = RightBoundary;
- levelStack[nStack++] = level+1;
- }
-
- /* Get the next node to process from the stack */
- Node = NodeStack[--nStack];
- Boundary = BoundaryStack[nStack];
- level = levelStack[nStack];
- }
-
- if (Node == NULL)
- continue; /* Dead end, go back to the stack loop */
-
- if (Animating)
- AnimateCheckInput();
-
- /* Map the sample into the screen coordinate system */
- Xs = Xsize*(Node->Sample->Xs+1)/2.0 - 0.5;
- Ys = Ysize*(Node->Sample->Ys+1)/2.0 - 0.5;
- Boundary.xH = Xsize*(Boundary.xH+1)/2.0 - 0.5;
- Boundary.xL = Xsize*(Boundary.xL+1)/2.0 - 0.5;
- Boundary.yL = Ysize*(Boundary.yL+1)/2.0 - 0.5;
- Boundary.yH = Ysize*(Boundary.yH+1)/2.0 - 0.5;
-
- /* Find the cell that the sample actually lies in */
- c = (int) floor( Xs );
- r = (int) floor( Ys );
- if (r >= y_start && r <= y_stop &&
- c >= x_start && c <= x_stop )
- image_data[r-y_start][c-x_start].samplesInPixel++;
-
- /* Find the rectangle pixels affected by the sample cell */
- rmn = (int) floor ( Boundary.yL - FilterRadius );
- rmx = (int) ceil ( Boundary.yH + FilterRadius );
- cmn = (int) floor ( Boundary.xL - FilterRadius );
- cmx = (int) ceil ( Boundary.xH + FilterRadius );
-
- /* loop over all affected pixels */
- for(r=rmn; r<rmx; r++) {
- if (r < y_start || r > y_stop) continue;
- for(c=cmn; c<cmx; c++) {
- if (c < x_start || c > x_stop) continue;
-
- /* Translate coordinates so that this affected pixel is at (0,0) and
- so that the filter radius is FilterSupport units long
- */
- yL = (FilterSupport * (Boundary.yL - r)) / FilterRadius;
- yH = (FilterSupport * (Boundary.yH - r)) / FilterRadius;
- xL = (FilterSupport * (Boundary.xL - c)) / FilterRadius;
- xH = (FilterSupport * (Boundary.xH - c)) / FilterRadius;
-
- /* Lookup the filter values */
- if (FilterFunction == Cubic) {
- Weight = IntegralLookup( xL, yL, xH, yH );
- } else {
- Weight = ( CdfLookup( xH ) - CdfLookup( xL) ) *
- ( CdfLookup( yH ) - CdfLookup( yL) );
- }
- pixel = &(image_data[r-y_start][c-x_start]);
- clr = &(Node->Sample->Ave);
- pixel->weight += Weight;
- pixel->clr.r += Weight*clr->r;
- pixel->clr.g += Weight*clr->g;
- pixel->clr.b += Weight*clr->b;
- pixel->clr.a += Weight*clr->a;
- }
- }
- }
- }
-
-
-
-
- ReSampleImage( Root, radius, stddevs )
- HierarchicalRegion *Root;
- double radius;
- double stddevs;
- {
- int xpixel, ypixel; /* The coordinate of the current pixel */
- FrameBufferType *FrameBuffer = NULL; /*WFF frame buffer for image*/
- FrameBufferType *NumRaysFB = NULL; /* for number-of-rays image */
- FloatColor pixelclr;
- static char *RGBABands = "RGBA";
- static char *IBandOnly = "I";
- char Value[ValueLength];
- int x, y;
- short inpixelcount;
- float totalW;
- float Radius;
-
- extern int y_stop, y_start, x_stop, x_start;
- extern double Aspect;
- extern FILE *image, *NumRaysImage;
- extern int Xsize, Ysize;
- int maxinpixel = 0;
- int Dims[2];
- Pixel *pixel;
-
- /* Allocate memory for the image */
- Dims[0] = y_stop - y_start + 1;
- Dims[1] = x_stop - x_start + 1;
- image_data = (Pixel **) mallocNd( 2, Dims, sizeof(Pixel) );
- assert( image_data );
- bzero( image_data[0], Dims[0]*Dims[1]*sizeof(Pixel) );
-
- /* Traverse the tree and filter the samples */
- Filter( Root, RootBoundary );
-
-
- /* Set up the frame buffer */
-
- OpenFB(&FrameBuffer);
- SetBounds(FrameBuffer, y_start, x_start, y_stop, x_stop);
- SetColorSystem(FrameBuffer, RGBABands, BitsPerBand);
- sprintf(Value, "%f", Aspect);
- SetDescriptor(FrameBuffer, "AspectRatio", Value);
- strcpy( Value, "RLE" );
- SetDescriptor(FrameBuffer, "Encoding", Value );
-
- PassImageOut(image, FrameBuffer);
-
- /*------------------------------------------------------------*/
- /* Initialize the number of rays image if it was requested. */
- /*------------------------------------------------------------*/
- if (NumRaysImage != NULL) {
- OpenFB(&NumRaysFB);
- SetBounds(NumRaysFB, y_start, x_start, y_stop, x_stop);
- SetColorSystem(NumRaysFB, IBandOnly, 8);
- sprintf(Value, "%f", Aspect);
- SetDescriptor(NumRaysFB, "AspectRatio", Value);
- strcpy( Value, "RLE");
- SetDescriptor( NumRaysFB, "Encoding", Value );
- PassImageOut(NumRaysImage, NumRaysFB);
- }
-
- fprintf(stderr,
- "Xsize: %d, Ysize: %d, x_start: %d, x_stop: %d, y_start: %d, y_stop: %d\n",
- Xsize, Ysize, x_start, x_stop, y_start, y_stop);
-
- maxinpixel = 0;
- for(y=y_start; y<=y_stop; y++) {
- for(x=x_start; x<=x_stop; x++) {
- pixel = &(image_data[y-y_start][x-x_start]);
- if (pixel->weight != 0) {
- pixel->clr.r /= pixel->weight;
- pixel->clr.g /= pixel->weight;
- pixel->clr.b /= pixel->weight;
- }
- Output( FrameBuffer, x, y, pixel->clr );
- if (NumRaysImage)
- NextPixelOut(NumRaysFB, &pixel->samplesInPixel);
- if (pixel->samplesInPixel > maxinpixel)
- maxinpixel = pixel->samplesInPixel;
- }
- }
-
- CloseFB(&FrameBuffer);
- if (NumRaysImage)
- CloseFB(&NumRaysFB);
- fprintf( stderr, "Maximum samples in pixel: %d\n", maxinpixel );
-
- }
-
- void ParseCommandLine(argc, argv)
- int argc;
- char **argv;
- {
- int nrays = 0;
-
- /* Jump over the command name */
- argc--; argv++;
-
- /* Parse the arguments */
- while (argc > 0) {
- if (argv[0][0] != '-') {
- fprintf(stderr, "Error in command line.\n");
- Usage();
- exit(-1);
- }
-
- /* Determine which switch, if any. */
-
- /**** Please keep these lexographically sorted! *****/
- switch (argv[0][1]) {
- case 'A':
- /* Set the aspect ratio of pixels (width/height) */
- Aspect = (double) atof(argv[1]);
- argc -= 2; argv += 2;
- break;
- case 'B':
- Animating = TRUE;
- argc--; argv++;
- break;
- case 'a':
- /* Set anitaliaing parameters */
- switch (argv[0][2]) {
- case 'B':
- B = atof(argv[1]);
- argc--; argv++;
- break;
- case 'C':
- CutOff = atof(argv[1]); /* For Sinc filter option */
- /* cutoff frequency in cycles-per-pixel */
- C = CutOff; /* For Cubic filter option */
- argc--; argv++;
- break;
- case 'F': {
- /* Set the filter function */
- char *string = argv[1];
- if (strcmp(string,"Gaussian") == 0)
- FilterFunction = Gaussian;
- else if (strcmp(string, "Sinc") == 0) {
- FilterFunction = Sinc;
- if (CutOff < 0.0) {
- CutOff = 1/2; /* Nyquist frequency: half of sample rate */
- }
- } else if (strcmp(string, "WindowedSinc") == 0) {
- FilterFunction = WindowedSinc;
- if (CutOff < 0.0) {
- CutOff = 1/2; /* Nyquist frequency: half of sample rate */
- }
- } else if (strcmp(string, "Cubic") == 0)
- FilterFunction = Cubic;
- else {
- fprintf( stderr, "Invalid filter type: %s\n\n", string );
- Usage();
- exit(1);
- }
- argc -= 1; argv += 1;
- break;
- }
- case 'f':
- /* Set the size of the support of the filter (in pixels) */
- FilterRadius = (double) atof(argv[1]);
- argc -= 1; argv += 1;
- break;
- case 'n':
- {
- char *nraysname = argv[1];
-
- /* Generate the nrays.im image */
- if ((NumRaysImage = fopen( nraysname, "w")) == NULL) {
- fprintf(stderr, "Can't open nrays.im image file.\n");
- Usage();
- exit(1);
- }
- argc -= 1; argv += 1;
- break;
- }
- case 's':
- /* Split nodes adaptively */
- AdaptiveSplits = TRUE;
- break;
- case 't':
- /* Set the width (in stddevs) of the truncated Gaussian */
- FilterSupport = (double) atof(argv[1]);
- argc -=1; argv += 1;
- break;
- default:
- fprintf(stderr, "Unknown antialiasing option: %c\n", argv[0][2]);
- Usage();
- exit(1);
- }
- argc -= 1; argv += 1;
- break;
- case 'b':
- BitsPerBand = atoi( argv[1] );
- argc -= 2; argv +=2;
- MaxOutBandValue = (1 << BitsPerBand) - 1;
- break;
- case 'i':
- /* Set the image file name */
- filename = argv[1];
- argc -= 2; argv += 2;
- break;
- case 'm':
- /* Set the maximum value expect in a color band */
- MaxInBandValue = atof( argv[1] );
- argc -= 2; argv += 2;
- break;
- case 's':
- /* Set the start and stop scan lines */
- y_start = atoi(argv[1]);
- y_stop = atoi(argv[2]);
- argc -= 3; argv += 3;
- break;
- case 'x':
- /* Set the x resolution */
- Xsize = atoi(argv[1]);
- x_start = 0;
- x_stop = Xsize-1;
- argc -=2; argv += 2;
- break;
- case 'y':
- /* Set the y resolution */
- Ysize = atoi(argv[1]);
- y_start = 0;
- y_stop = Ysize-1;
- argc -=2; argv += 2;
- break;
- case 'w':
- /* Set the entire scanning window */
- x_start = atoi(argv[1]);
- x_stop = atoi(argv[2]);
- y_start = atoi(argv[3]);
- y_stop = atoi(argv[4]);
- argc -= 5; argv += 5;
- break;
- default:
- fprintf(stderr, "bad option: %s\n", argv[0]);
- Usage();
- exit(-1);
- }
- }
- }
-
-
-
- main( argc, argv)
- int argc;
- char *argv[];
- {
- RectType Boundary; /* Boundary of interesting region */
-
- ParseCommandLine(argc, argv);
-
- if (filename == NULL)
- image = stdout;
- else
- image = fopen( filename, "w" );
- if (image == NULL)
- {
- fprintf( stderr, "Unable to open output file\n" );
- exit(1);
- }
-
- PixelSizeX = 2.0/((double) Xsize);
- PixelSizeY = 2.0/((double) Ysize);
-
- Boundary.xL = -1.0 + x_start*PixelSizeX - PixelSizeX*FilterRadius;
- Boundary.xH = -1.0 + (x_stop+1)*PixelSizeX + PixelSizeX*FilterRadius;
- Boundary.yL = -1.0 + y_start*PixelSizeY - PixelSizeY*FilterRadius;
- Boundary.yH = -1.0 + (y_stop+1)*PixelSizeY + PixelSizeY*FilterRadius;
-
- if (Animating) {
- Animate("");
- AnimateInitialize( Boundary.xL, Boundary.yL, Boundary.xH, Boundary.yH );
- }
-
-
- /* Read the samples in */
- ReadSampleFile( stdin, &Boundary );
-
- /* Filter and resample at the screen resolution */
- ReSampleImage( &Root, FilterRadius, FilterSupport );
-
- if (Animating)
- AnimateExit();
-
- return 0;
-
- }
-
-
- Output(FrameBuffer, x, y, c)
- FrameBufferType *FrameBuffer;
- int x, y;
- FloatColor c;
- {
- int red, green, blue, alpha;
- unsigned short pixel[4];
-
- if ((red = (int) (c.r/MaxInBandValue * MaxOutBandValue + 0.5))
- > MaxOutBandValue) red = MaxOutBandValue;
- if (red < 0) red = 0;
-
- if ((green = (int) (c.g/MaxInBandValue * MaxOutBandValue + 0.5))
- > MaxOutBandValue) green = MaxOutBandValue;
- if (green < 0) green = 0;
-
- if ((blue = (int) (c.b/MaxInBandValue * MaxOutBandValue + 0.5))
- > MaxOutBandValue) blue = MaxOutBandValue;
- if (blue < 0) blue = 0;
-
- if ((alpha = (int) (c.a * MaxOutBandValue + 0.5))
- >MaxOutBandValue) alpha = MaxOutBandValue;
- if (alpha < 0) alpha = 0;
-
- pixel[0] = red;
- pixel[1] = green;
- pixel[2] = blue;
- pixel[3] = alpha;
-
- NextPixelOut(FrameBuffer, pixel);
-
- }
-
- Usage()
- {
-
- fprintf( stderr, "\
- Usage: Reconstruct [options].\n\
- Options are:\n\
- -aB val -aC val \"Mitchell\" parameters for cubic filter. \n\
- -aC cutoff Cutoff wavelength for Sinc filter. In cycles/pixel.\n\
- -aF [ Cubic | Filter function \n\
- Gaussian | \n\
- Sinc | \n\
- WindowedSinc ] \n\
- -af radius Filter radius (in pixels). \n\
- -an filename Generate an image showing number of samples.\n\
- -as Split nodes adaptively.\n\
- -at support Width of gaussian filter (in stddevs).\n\
- \n\
- -A aspect Set aspect ration\n\
- -i filename Set result file name\n\
- -x xsize Set the resolution of the image in the x direction.\n\
- -y ysize Set the resolution of the image in the y direction.\n\
- -s y_start x_start Set the start and stop scan lines\n\
- -m value Set the maximum value expected in a color band\n\
- -w xmin xmax ymin ymax Set the entire scan window\n\
- ");
- }
-
-